Chapter 01

Pine Script란 무엇인가?

1.1 Pine Script 개요

Pine Script는 TradingView 플랫폼 전용으로 설계된 경량 프로그래밍 언어입니다. 트레이더가 자신만의 커스텀 기술적 지표(Indicator), 자동매매 전략(Strategy), 그리고 라이브러리(Library)를 만들 수 있도록 해줍니다. TradingView 차트 위에서 직접 실행되므로 별도의 소프트웨어 설치나 서버 설정이 전혀 필요하지 않습니다.

일반적인 프로그래밍 언어(Python, JavaScript 등)와 달리, Pine Script는 금융 데이터 처리와 차트 시각화에 특화되어 있습니다. 복잡한 수학 연산이나 네트워크 통신 대신, "이 가격이 이 조건을 만족하면 차트에 이렇게 표시하라" 혹은 "이 조건에서 매수/매도하라"와 같은 트레이딩 로직을 간결하게 표현하는 데 최적화되어 있습니다.

1.2 왜 Pine Script를 배워야 하는가?

TradingView에는 이미 수천 개의 내장 지표와 커뮤니티 스크립트가 있습니다. 그런데도 Pine Script를 직접 배워야 하는 이유는 무엇일까요?

  • 나만의 전략 구현 : 모든 트레이더의 매매 기준은 다릅니다. 기존 지표를 조합하거나 자신만의 고유한 논리를 코드로 구현할 수 있습니다.
  • 백테스팅 : 과거 데이터로 전략을 검증하여 실전 투자 전에 성과를 확인할 수 있습니다. "이 전략이 지난 3년간 어떤 수익률을 보였을까?"를 코드 몇 줄로 확인 가능합니다.
  • 자동 알림 : 특정 조건이 충족되면 이메일, 앱 푸시, 웹훅(Webhook)으로 알림을 보내 실시간 대응이 가능합니다.
  • 커뮤니티 공유 : 자신이 만든 지표를 전 세계 트레이더와 공유하거나 판매할 수 있습니다.
  • 학습 곡선이 낮음 : 프로그래밍 경험이 없는 트레이더도 비교적 빠르게 배울 수 있도록 설계되어 있습니다.

1.3 Pine Script의 세 가지 스크립트 유형

유형선언 함수역할백테스팅
인디케이터 (Indicator)indicator()차트에 시각적 정보를 표시 (이동평균, RSI 등)불가
전략 (Strategy)strategy()매수/매도 주문을 시뮬레이션하고 성과 분석가능
라이브러리 (Library)library()다른 스크립트에서 재사용할 함수 모음해당 없음

인디케이터는 분석 도구이고, 전략은 실제 매매 시뮬레이션입니다. 둘의 가장 큰 차이는 전략만 "Strategy Tester" 탭에서 백테스팅 결과(승률, 수익률, 최대 낙폭 등)를 보여준다는 점입니다.

1.4 Pine Script 버전 역사

Pine Script는 지속적으로 발전해 왔습니다. 2024년 말 v6가 출시되어 현재 최신 버전입니다. 각 버전은 이전 버전과 호환되지 않는 변경사항이 있으므로, 스크립트 상단에 반드시 버전을 명시해야 합니다.

버전주요 변경점
v1 ~ v3초기 버전, 현재는 거의 사용되지 않음
v4네임스페이스 도입 (ta., math. 등), 구조 개선
v5라이브러리 지원, 타입 시스템 강화, switch문 추가
v6동적 request, 엄격한 boolean 로직, 정수 나눗셈 수정, 무제한 백테스팅 등
참고: 이 튜토리얼은 Pine Script v6을 기준으로 작성되었습니다. v5 사용자도 대부분의 개념을 동일하게 적용할 수 있으나, 일부 문법 차이가 있을 수 있습니다.
Chapter 02

TradingView 환경 설정

2.1 TradingView 계정 만들기

Pine Script를 사용하려면 TradingView 계정이 필요합니다. 무료 계정(Basic)으로도 Pine Script 작성과 실행이 가능하지만, 무료 플랜에서는 동시에 차트에 적용할 수 있는 지표 수에 제한이 있습니다. tradingview.com에서 회원가입을 완료하면 바로 시작할 수 있습니다.

2.2 Pine Editor 열기

Pine Editor는 TradingView 차트 화면 하단에 위치합니다. 차트를 열면 화면 아래쪽에 "Pine Editor" 탭이 보입니다. 이 탭을 클릭하면 코드를 작성할 수 있는 에디터 창이 나타납니다. 처음 열면 기본 템플릿 코드가 표시되어 있을 수 있습니다.

2.3 첫 번째 스크립트 실행하기

에디터에 아래 코드를 입력한 후, "차트에 추가(Add to chart)" 버튼을 클릭하면 차트 위에 종가 기반의 14일 이동평균선이 표시됩니다.

Pine Script
// 이것이 여러분의 첫 번째 Pine Script입니다!
//@version=6
indicator("나의 첫 지표", overlay = true)

// 14일 단순이동평균 계산
myMA = ta.sma(close, 14)

// 차트에 선으로 표시
plot(myMA, color = color.blue, linewidth = 2)

2.4 Pine Editor 핵심 기능

  • 차트에 추가 : 작성한 스크립트를 현재 차트에 적용합니다.
  • 저장 : 스크립트를 "내 스크립트" 목록에 저장합니다.
  • 열기 : 이전에 저장한 스크립트를 불러옵니다.
  • 자동완성 : 코드 작성 중 Ctrl+Space를 누르면 함수/변수명을 자동완성할 수 있습니다.
  • 콘솔/에러 창 : 문법 오류가 발생하면 에디터 하단에 에러 메시지가 표시됩니다.
  • 버전 변환 : "더보기(More)" 메뉴에서 코드를 최신 버전으로 자동 변환할 수 있습니다.
Tip! Pine Editor에서 함수 위에 마우스를 올리면(hover) 해당 함수의 설명이 팝업으로 표시됩니다. 또한 Ctrl+클릭으로 공식 레퍼런스 문서로 바로 이동할 수 있습니다.

2.5 TradingView 요금제와 Pine Script

무료 플랜에서도 Pine Script의 거의 모든 기능을 사용할 수 있습니다. 다만 유료 플랜으로 갈수록 동시 적용 가능한 지표 수, 서버측 알림 수, 차트에 표시 가능한 바(Bar) 수 등이 증가합니다. Pine Script 학습 자체는 무료 플랜으로 충분합니다.

Chapter 03

스크립트 구조와 버전 선언

3.1 스크립트의 기본 구조

모든 Pine Script는 다음과 같은 구조를 따릅니다. 버전 선언 → 스크립트 타입 선언 → 계산 로직 → 출력(시각화)의 흐름입니다.

Pine Script
// ① 버전 선언 (항상 첫 줄)
//@version=6

// ② 스크립트 유형 선언 (indicator, strategy, library 중 택1)
indicator("스크립트 이름", overlay = true)

// ③ 입력값 정의 (사용자가 설정에서 변경 가능)
length = input.int(14, "기간")

// ④ 계산 로직
smaValue = ta.sma(close, length)

// ⑤ 시각화 출력
plot(smaValue, "SMA", color = color.orange)

3.2 버전 주석 (//@version=6)

스크립트 최상단에 위치하는 //@version=6은 Pine Script 컴파일러에게 이 코드가 어떤 버전의 문법을 사용하는지 알려줍니다. 이 선언이 없으면 에러가 발생합니다. 새로 작성하는 스크립트는 항상 최신 버전(v6)을 사용하세요.

3.3 indicator() 선언문

indicator() 함수는 이 스크립트가 인디케이터임을 선언합니다. 가장 중요한 파라미터는 다음과 같습니다.

파라미터설명기본값
title지표 이름 (차트에서 표시)필수
shorttitle짧은 이름title과 동일
overlaytrue: 메인 차트 위에 표시 / false: 별도 패널false
max_bars_back과거 데이터 참조 최대 바 수자동
timeframe지표의 타임프레임 (멀티 타임프레임용)""
Pine Script
// 메인 차트 위에 오버레이
indicator("볼린저 밴드", shorttitle = "BB", overlay = true)

// 별도 하단 패널에 표시 (RSI처럼)
indicator("나의 RSI", overlay = false)

3.4 실행 모델 이해하기

Pine Script의 실행 방식은 일반 프로그래밍 언어와 크게 다릅니다. 스크립트는 차트의 각 봉(Bar)마다 왼쪽에서 오른쪽으로, 즉 과거에서 현재로 한 번씩 순차적으로 실행됩니다. 차트에 1000개의 봉이 있으면 스크립트는 1000번 실행되는 것입니다.

이 "바-by-바" 실행 모델 덕분에 close는 항상 "현재 실행 중인 봉의 종가"를 의미하고, close[1]은 "한 봉 전의 종가"를 의미합니다. 이 개념은 Pine Script를 이해하는 데 핵심적입니다.

중요! Pine Script는 반복문(loop)을 사용하지 않아도 모든 봉에 대해 자동으로 반복 실행됩니다. for문으로 모든 봉을 순회할 필요가 없습니다. 이것이 일반 프로그래밍 언어와의 가장 큰 차이점입니다.

3.5 주석 작성법

Pine Script
// 한 줄 주석: 슬래시 두 개 뒤의 모든 텍스트

// Pine Script v6에는 여러 줄 주석(/* */)이 없습니다.
// 여러 줄을 주석 처리하려면 각 줄 앞에 // 를 붙여야 합니다.
Chapter 04

데이터 타입과 변수

4.1 기본 데이터 타입

Pine Script는 강력한 타입 시스템을 갖추고 있습니다. 변수를 선언하면 컴파일러가 자동으로 타입을 추론하지만, 명시적으로 선언할 수도 있습니다.

타입설명예시
int정수14, -3, 0
float실수(소수점)3.14, -0.5, 100.0
bool참/거짓true, false
string문자열"Hello", "매수"
color색상color.red, #ff0000
na값 없음 (Not Available)na

4.2 변수 선언 방식

Pine Script
//@version=6
indicator("변수 예시")

// 1. 타입 추론 (자동으로 타입 결정)
myLength = 14              // int
myPrice  = 3.14            // float
isUp     = close > open    // bool
myText   = "상승"           // string

// 2. 명시적 타입 선언
int   period  = 20
float ratio   = 0.618
bool  bullish = true
string status = "대기"

// 3. var 키워드: 첫 봉에서만 초기화, 이후 값 유지
var int counter = 0
counter += 1  // 매 봉마다 1씩 증가 (값이 누적됨)

// 4. varip 키워드: 실시간 봉에서 틱마다 유지
varip int tickCount = 0
tickCount += 1

plot(counter)

4.3 var vs 일반 변수의 차이

Pine Script에서 가장 헷갈리는 부분 중 하나입니다. 일반 변수는 매 봉마다 다시 계산되어 초기화됩니다. 반면 var로 선언한 변수는 첫 번째 봉에서만 초기화되고, 이후에는 마지막으로 할당된 값을 유지합니다.

Pine Script
//@version=6
indicator("var 비교")

// 일반 변수: 매 봉마다 0으로 초기화됨
int normalVar = 0
if close > open
    normalVar := 1   // 양봉이면 1, 아니면 항상 0

// var 변수: 값이 봉 간에 유지됨
var int persistVar = 0
if close > open
    persistVar += 1  // 양봉 횟수 누적 카운트

plot(normalVar, "일반", color = color.red)
plot(persistVar, "누적", color = color.blue)

4.4 na (Not Available) 값

na는 "값이 존재하지 않음"을 뜻하는 특별한 값입니다. 예를 들어 14일 이동평균을 구할 때, 처음 13개 봉에서는 데이터가 부족하므로 결과가 na가 됩니다. na 값을 비교할 때는 == 대신 na() 함수를 사용해야 합니다.

Pine Script
// na 확인 방법
myValue = ta.sma(close, 14)

// ✗ 잘못된 방법
// if myValue == na

// ✓ 올바른 방법
if na(myValue)
    myValue := 0

// nz() 함수: na를 지정 값(기본 0)으로 대체
safeValue = nz(myValue, 0)

4.5 히스토리 참조 연산자 []

대괄호 []를 사용하면 이전 봉의 값을 참조할 수 있습니다. close[1]은 1봉 전의 종가, close[5]는 5봉 전의 종가입니다. 이것은 Pine Script의 핵심 기능으로, 과거 데이터를 기반으로 현재 조건을 판단하는 데 사용됩니다.

Pine Script
// 이전 봉 데이터 참조
prevClose  = close[1]    // 1봉 전 종가
prev5High  = high[5]     // 5봉 전 고가
prev10Vol  = volume[10]  // 10봉 전 거래량

// 활용 예: 종가가 전 봉 대비 상승했는지?
priceUp = close > close[1]
Chapter 05

연산자와 조건문

5.1 산술 연산자

연산자의미예시
+덧셈close + 100
-뺄셈high - low
*곱셈close * 1.02
/나눗셈 (v6: 실수 결과)5 / 2 → 2.5
%나머지bar_index % 5

5.2 비교 연산자

연산자의미예시
==같다close == open
!=같지 않다close != open
>크다close > open
<작다close < open
>=크거나 같다volume >= 1000000
<=작거나 같다rsi <= 30

5.3 논리 연산자

Pine Script
// and : 둘 다 참이어야 참
bullish = close > open and volume > volume[1]

// or : 둘 중 하나만 참이면 참
signal = rsiValue < 30 or macdHist > 0

// not : 반대
bearish = not bullish

5.4 조건문 (if / else)

Pine Script
// 기본 if문
if close > open
    label.new(bar_index, high, "양봉")

// if - else
string trend = ""
if close > ta.sma(close, 200)
    trend := "상승 추세"
else
    trend := "하락 추세"

// if - else if - else
color barColor = color.gray
if close > open * 1.02
    barColor := color.green    // 2% 이상 상승
else if close < open * 0.98
    barColor := color.red      // 2% 이상 하락
else
    barColor := color.gray     // 보합

5.5 삼항 연산자 (?:)

간단한 조건은 한 줄로 표현할 수 있습니다. 조건 ? 참일때값 : 거짓일때값 형태입니다.

Pine Script
// 양봉이면 초록, 음봉이면 빨강
candleColor = close > open ? color.green : color.red

// 거래량이 평균 이상이면 "활발", 아니면 "소강"
volStatus = volume > ta.sma(volume, 20) ? "활발" : "소강"

// 중첩 삼항 (복잡하면 if문 사용 권장)
grade = score >= 90 ? "A" : score >= 70 ? "B" : "C"

5.6 switch문

Pine Script
// switch문으로 여러 조건 분기
dayOfWeek = dayofweek
string dayName = switch dayOfWeek
    dayofweek.monday    => "월요일"
    dayofweek.tuesday   => "화요일"
    dayofweek.wednesday => "수요일"
    dayofweek.thursday  => "목요일"
    dayofweek.friday    => "금요일"
    => "주말"
Chapter 06

내장 변수 - 시세 데이터

6.1 가격 관련 내장 변수

Pine Script는 현재 봉의 가격 데이터를 전역 내장 변수로 제공합니다. 이 변수들은 별도의 선언 없이 바로 사용할 수 있습니다.

변수설명활용 예
open현재 봉의 시가갭 상승/하락 판별
high현재 봉의 고가저항선 계산
low현재 봉의 저가지지선 계산
close현재 봉의 종가이동평균 계산 (가장 많이 사용)
volume현재 봉의 거래량거래량 돌파 확인
hl2(high + low) / 2중간값
hlc3(high + low + close) / 3전형적 가격
ohlc4(open + high + low + close) / 4평균 가격

6.2 시간/바 관련 내장 변수

변수설명
bar_index현재 봉의 인덱스 (0부터 시작)
time현재 봉의 시작 시간 (UNIX 타임스탬프, 밀리초)
time_close현재 봉의 종료 시간
last_bar_index차트의 마지막 봉 인덱스
barstate.isconfirmed현재 봉이 확정됐는지 (실시간에서 중요)
barstate.islast현재 봉이 마지막 봉인지
barstate.isrealtime실시간 데이터인지 (히스토리 vs 라이브)

6.3 심볼 정보 변수 (syminfo)

Pine Script
// 현재 차트의 심볼 정보
plot(0, title = syminfo.ticker)        // "BTCUSDT"
// syminfo.currency    → "USD"
// syminfo.type        → "crypto"
// syminfo.timezone    → "Etc/UTC"
// syminfo.mintick     → 0.01 (최소 호가 단위)
// syminfo.pointvalue  → 1 (포인트당 가치)

6.4 타임프레임 변수

Pine Script
// 현재 차트의 타임프레임 확인
// timeframe.period      → "60" (1시간봉), "D" (일봉), "W" (주봉)
// timeframe.isintraday  → true (분봉/시간봉)
// timeframe.isdaily     → true (일봉)
// timeframe.isweekly    → true (주봉)
// timeframe.ismonthly   → true (월봉)

// 활용: 타임프레임에 따라 다른 기간 적용
maLength = timeframe.isintraday ? 50 : 20
핵심 개념: Pine Script의 내장 변수는 항상 "현재 실행 중인 봉"의 데이터를 가리킵니다. close가 현재 봉의 종가이고, close[1]이 이전 봉의 종가인 것처럼, 시간 축에서의 위치가 자동으로 결정됩니다.
Chapter 07

plot() - 차트에 데이터 시각화

7.1 plot() 기본 사용법

plot()은 Pine Script에서 가장 자주 사용하는 함수입니다. 숫자 값을 차트 위에 선으로 그려줍니다.

Pine Script
//@version=6
indicator("Plot 예시", overlay = true)

// 가장 기본적인 plot
plot(close)

// 파라미터를 활용한 plot
plot(ta.sma(close, 20), title = "SMA 20", color = color.orange, linewidth = 2)
plot(ta.sma(close, 50), title = "SMA 50", color = color.blue, linewidth = 2)

7.2 plot() 주요 파라미터

파라미터설명예시
series표시할 값 (필수)close, ta.sma(close, 14)
title범례에 표시될 이름"SMA 20"
color선 색상color.red, #ff0000
linewidth선 굵기 (1~4)2
style선 스타일plot.style_line, plot.style_histogram
offset좌우 이동 (봉 수)-1 (왼쪽으로 1봉)
display표시 위치display.all, display.pane

7.3 plot 스타일 종류

Pine Script
//@version=6
indicator("Plot 스타일")

src = close
avg = ta.sma(src, 14)
diff = src - avg

// 다양한 스타일
plot(diff, style = plot.style_line)          // 일반 선 (기본)
plot(diff, style = plot.style_histogram)     // 히스토그램 (MACD용)
plot(diff, style = plot.style_columns)       // 막대 (거래량용)
plot(diff, style = plot.style_area)          // 채워진 영역
plot(diff, style = plot.style_circles)       // 점
plot(diff, style = plot.style_cross)         // X 표시
plot(diff, style = plot.style_stepline)      // 계단식 선

7.4 hline()과 fill()

hline()은 수평선을 그리고, fill()은 두 plot이나 hline 사이를 색으로 채웁니다.

Pine Script
//@version=6
indicator("RSI with Zones")

rsi = ta.rsi(close, 14)

// RSI 그리기
rsiPlot = plot(rsi, "RSI", color = color.purple, linewidth = 2)

// 수평선 (과매수/과매도 기준선)
upper = hline(70, "과매수", color = color.red)
lower = hline(30, "과매도", color = color.green)
hline(50, "중앙", color = color.gray, linestyle = hline.style_dotted)

// 과매수/과매도 영역 채우기
fill(upper, lower, color = color.new(color.purple, 90))
Tip! color.new(color.blue, 80)에서 두 번째 인자는 투명도(0~100)입니다. 0은 불투명, 100은 완전 투명입니다. fill()에 사용할 때 80~95 정도의 높은 투명도를 주면 차트를 가리지 않으면서 영역을 표시할 수 있습니다.
Chapter 08

input() - 사용자 설정값 받기

8.1 input이 필요한 이유

지표의 파라미터를 코드에 직접 하드코딩하면, 값을 바꿀 때마다 코드를 수정해야 합니다. input() 함수를 사용하면 사용자가 설정 탭에서 GUI로 값을 변경할 수 있어, 코드 수정 없이 다양한 파라미터를 실험할 수 있습니다.

8.2 input 함수 종류

함수입력 타입예시
input.int()정수이동평균 기간 (14, 20, 50...)
input.float()실수ATR 배수 (1.5, 2.0...)
input.bool()체크박스기능 활성화/비활성화
input.string()텍스트/드롭다운이동평균 유형 선택
input.color()색상 선택기선 색상 변경
input.source()가격 소스 선택close, open, hl2...
input.timeframe()타임프레임"5", "15", "60", "D"
input.symbol()심볼"BINANCE:BTCUSDT"
input.time()날짜/시간특정 시점 지정

8.3 input 실전 예시

Pine Script
//@version=6
indicator("커스텀 이동평균", overlay = true)

// 정수 입력: 이동평균 기간
length = input.int(20, "MA 기간", minval = 1, maxval = 500)

// 드롭다운 선택: 이동평균 유형
maType = input.string("SMA", "MA 유형", 
     options = ["SMA", "EMA", "WMA", "RMA"])

// 소스 선택: 어떤 가격을 기준으로 할지
src = input.source(close, "소스")

// 색상 선택
maColor = input.color(color.orange, "MA 색상")

// 체크박스: 기능 토글
showFill = input.bool(true, "영역 채우기 표시")

// 이동평균 유형에 따라 계산
float maValue = switch maType
    "SMA" => ta.sma(src, length)
    "EMA" => ta.ema(src, length)
    "WMA" => ta.wma(src, length)
    "RMA" => ta.rma(src, length)

// 출력
maPlot = plot(maValue, "MA", color = maColor, linewidth = 2)
pricePlot = plot(close, "종가", display = display.none)

if showFill
    fillColor = close > maValue ? color.new(color.green, 90) : color.new(color.red, 90)
    fill(maPlot, pricePlot, color = fillColor)

8.4 input 그룹과 툴팁

Pine Script
// 그룹으로 관련 설정을 묶기
grpMA = "이동평균 설정"
length1 = input.int(20, "단기 MA", group = grpMA)
length2 = input.int(50, "장기 MA", group = grpMA)

grpRisk = "리스크 관리"
stopLoss = input.float(2.0, "손절 %", group = grpRisk, 
    tooltip = "진입가 대비 손절 비율 (%)")
takeProfit = input.float(4.0, "익절 %", group = grpRisk,
    tooltip = "진입가 대비 목표 비율 (%)")
Chapter 09

기술적 분석 함수 (ta.* 네임스페이스)

9.1 이동평균 함수

Pine Script는 ta.* 네임스페이스에 수십 가지의 기술적 분석 함수를 내장하고 있습니다. 별도의 라이브러리 설치 없이 바로 사용 가능합니다.

Pine Script
// 주요 이동평균 함수
sma20  = ta.sma(close, 20)    // 단순이동평균 (Simple)
ema12  = ta.ema(close, 12)    // 지수이동평균 (Exponential)
wma10  = ta.wma(close, 10)    // 가중이동평균 (Weighted)
rma14  = ta.rma(close, 14)    // 와일더 이동평균 (RSI 계산에 사용)
vwma20 = ta.vwma(close, 20)   // 거래량가중이동평균

9.2 오실레이터 함수

Pine Script
// RSI (Relative Strength Index)
rsi14 = ta.rsi(close, 14)

// MACD
[macdLine, signalLine, histLine] = ta.macd(close, 12, 26, 9)

// Stochastic
stochK = ta.stoch(close, high, low, 14)
stochD = ta.sma(stochK, 3)

// ATR (Average True Range) - 변동성 측정
atr14 = ta.atr(14)

// Bollinger Bands
[bbUpper, bbMiddle, bbLower] = ta.bb(close, 20, 2.0)

// SuperTrend
[supertrend, direction] = ta.supertrend(3.0, 10)

9.3 크로스 탐지 함수

두 값이 교차하는 시점을 탐지하는 함수는 매매 신호 생성에 핵심적입니다.

Pine Script
fast = ta.ema(close, 12)
slow = ta.ema(close, 26)

// 골든크로스: 단기선이 장기선을 상향 돌파
goldenCross = ta.crossover(fast, slow)

// 데드크로스: 단기선이 장기선을 하향 돌파
deadCross = ta.crossunder(fast, slow)

// cross: 어느 방향이든 교차
anyCross = ta.cross(fast, slow)

9.4 최고가/최저가 함수

Pine Script
// 최근 N봉 중 최고가 / 최저가
highest20 = ta.highest(high, 20)   // 20봉 최고가
lowest20  = ta.lowest(low, 20)    // 20봉 최저가

// 최고가 발생 위치 (몇 봉 전?)
highBars = ta.highestbars(high, 20)  // 음수로 반환 (예: -5)

// 특정 조건 이후 경과 봉 수
barsSince = ta.barssince(ta.crossover(fast, slow))

// 피벗 포인트 (고점/저점 감지)
pivotHigh = ta.pivothigh(5, 5)  // 좌우 5봉 기준 고점
pivotLow  = ta.pivotlow(5, 5)   // 좌우 5봉 기준 저점
Chapter 10

실전 인디케이터 만들기

10.1 골든크로스/데드크로스 지표

가장 기본적이면서도 실용적인 매매 신호 지표를 만들어 보겠습니다. 단기 이동평균과 장기 이동평균의 교차를 감지하고, 시각적으로 표시합니다.

Pine Script
//@version=6
indicator("골든/데드 크로스", overlay = true)

// 사용자 설정
fastLen = input.int(20, "단기 MA 기간", minval = 1)
slowLen = input.int(60, "장기 MA 기간", minval = 1)
maType  = input.string("EMA", "MA 유형", options = ["SMA", "EMA"])

// 이동평균 계산
fastMA = maType == "EMA" ? ta.ema(close, fastLen) : ta.sma(close, fastLen)
slowMA = maType == "EMA" ? ta.ema(close, slowLen) : ta.sma(close, slowLen)

// 크로스 감지
bullCross = ta.crossover(fastMA, slowMA)
bearCross = ta.crossunder(fastMA, slowMA)

// 추세 색상
trendColor = fastMA > slowMA ? color.green : color.red

// 이동평균 플롯
plot(fastMA, "단기 MA", color = color.orange, linewidth = 2)
plot(slowMA, "장기 MA", color = color.blue, linewidth = 2)

// 교차 시점에 도형 표시
plotshape(bullCross, "매수", shape.triangleup, 
    location.belowbar, color.green, size = size.small)
plotshape(bearCross, "매도", shape.triangledown, 
    location.abovebar, color.red, size = size.small)

// 배경색으로 추세 표시
bgcolor(color.new(trendColor, 95))

10.2 볼린저 밴드 + RSI 복합 지표

Pine Script
//@version=6
indicator("BB + RSI 복합 신호", overlay = true)

// 볼린저 밴드
bbLen   = input.int(20, "BB 기간")
bbMult  = input.float(2.0, "BB 표준편차")
[upper, middle, lower] = ta.bb(close, bbLen, bbMult)

// RSI
rsiLen  = input.int(14, "RSI 기간")
rsi     = ta.rsi(close, rsiLen)

// 복합 조건: BB 하단 터치 + RSI 과매도 = 강한 매수 신호
strongBuy  = close <= lower and rsi < 30
strongSell = close >= upper and rsi > 70

// 시각화
p1 = plot(upper, "상단", color = color.gray)
plot(middle, "중앙", color = color.gray, linewidth = 1)
p2 = plot(lower, "하단", color = color.gray)
fill(p1, p2, color = color.new(color.blue, 95))

// 강한 신호에 마커 표시
plotshape(strongBuy, "강한 매수", shape.labelup,
    location.belowbar, color.green, text = "BUY", textcolor = color.white)
plotshape(strongSell, "강한 매도", shape.labeldown,
    location.abovebar, color.red, text = "SELL", textcolor = color.white)
주의! 지표가 표시하는 매수/매도 신호는 참고용입니다. 어떤 단일 지표도 100% 정확한 매매 시점을 알려줄 수 없습니다. 반드시 다른 분석 방법과 함께 사용하고, 리스크 관리를 병행하세요.
Chapter 11

조건부 색상과 배경

11.1 동적 색상 적용

Pine Script의 강력한 기능 중 하나는 조건에 따라 색상을 동적으로 변경하는 것입니다. 이를 통해 한눈에 시장 상황을 파악할 수 있는 직관적인 차트를 만들 수 있습니다.

Pine Script
//@version=6
indicator("동적 색상", overlay = true)

ma = ta.ema(close, 20)

// 조건에 따라 색상 변경
maColor = close > ma ? color.green : color.red
plot(ma, color = maColor, linewidth = 3)

// 거래량 강도에 따른 그라데이션
volAvg = ta.sma(volume, 20)
volRatio = volume / volAvg
volColor = color.from_gradient(volRatio, 0.5, 2.0, color.gray, color.yellow)

// 캔들 색상 직접 지정
bodyColor = close > open ? color.new(color.green, 20) : color.new(color.red, 20)
barcolor(bodyColor)

11.2 bgcolor() - 배경색

Pine Script
// RSI 구간별 배경색
rsi = ta.rsi(close, 14)

bgCol = rsi > 70 ? color.new(color.red, 90) :
         rsi < 30 ? color.new(color.green, 90) :
         na

bgcolor(bgCol, title = "RSI 영역")

// 장 시작/마감 시간 하이라이트 (주식)
isOpen = hour == 9 and minute < 30
bgcolor(isOpen ? color.new(color.blue, 92) : na)

11.3 color.from_gradient() - 그라데이션

color.from_gradient()는 값의 범위에 따라 색상을 부드럽게 전환합니다. RSI가 0에 가까우면 초록, 100에 가까우면 빨강으로 변하는 식입니다.

Pine Script
//@version=6
indicator("RSI 그라데이션")

rsi = ta.rsi(close, 14)

// RSI 값에 따라 초록(0) → 노랑(50) → 빨강(100) 그라데이션
rsiColor = color.from_gradient(rsi, 20, 80, color.green, color.red)

plot(rsi, color = rsiColor, linewidth = 3, style = plot.style_columns)
hline(70)
hline(30)
Chapter 12

도형과 라벨 (plotshape, label, line)

12.1 plotshape() - 조건부 도형

plotshape()는 특정 조건이 참일 때 차트에 도형을 표시합니다. 매수/매도 신호를 눈에 띄게 표시할 때 유용합니다.

Pine Script
// 사용 가능한 shape 종류:
// shape.triangleup, shape.triangledown
// shape.circle, shape.cross, shape.diamond
// shape.labelup, shape.labeldown
// shape.flag, shape.arrowup, shape.arrowdown

buySignal  = ta.crossover(ta.rsi(close, 14), 30)
sellSignal = ta.crossunder(ta.rsi(close, 14), 70)

plotshape(buySignal, "매수", shape.arrowup,
    location.belowbar, color.green, size = size.normal)
plotshape(sellSignal, "매도", shape.arrowdown,
    location.abovebar, color.red, size = size.normal)

12.2 label.new() - 동적 라벨

라벨은 더 복잡한 텍스트 정보를 차트에 표시할 때 사용합니다. plotshape와 달리 텍스트 내용을 자유롭게 커스터마이징할 수 있습니다.

Pine Script
//@version=6
indicator("라벨 예시", overlay = true)

// 마지막 봉에 현재 가격 라벨 표시
if barstate.islast
    priceLabel = label.new(
         bar_index, close,
         text = "현재가: " + str.tostring(close, "#.##"),
         color = color.blue,
         textcolor = color.white,
         style = label.style_label_left,
         size = size.normal
         )
    // 이전 라벨 삭제 (중복 방지)
    label.delete(priceLabel[1])

12.3 line.new() - 동적 선

Pine Script
// 피벗 고점/저점에 수평선 그리기
pivHigh = ta.pivothigh(5, 5)

if not na(pivHigh)
    line.new(
         bar_index[5], pivHigh,
         bar_index, pivHigh,
         color = color.red,
         style = line.style_dashed,
         extend = extend.right,
         width = 1
         )
리소스 제한: TradingView는 차트에 표시할 수 있는 라벨과 선의 수를 제한합니다. 기본적으로 약 500개까지 유지되며, 초과하면 가장 오래된 것부터 자동 삭제됩니다. max_labels_countmax_lines_count 파라미터로 이 제한을 조정할 수 있습니다.
Chapter 13

전략(Strategy) 기초

13.1 전략 vs 인디케이터

인디케이터가 "분석 도구"라면, 전략은 "매매 시뮬레이터"입니다. 전략 스크립트는 가상의 주문을 넣고, 과거 데이터로 그 성과를 검증(백테스팅)할 수 있습니다. strategy() 함수로 선언하면 자동으로 Strategy Tester 탭이 활성화됩니다.

13.2 strategy() 선언

Pine Script
//@version=6
strategy("나의 첫 전략", 
     overlay = true,                // 메인 차트 위에 표시
     initial_capital = 10000,       // 초기 자본금 ($10,000)
     default_qty_type = strategy.percent_of_equity,
     default_qty_value = 10,        // 자본금의 10%씩 거래
     commission_type = strategy.commission.percent,
     commission_value = 0.1,        // 수수료 0.1%
     slippage = 1                    // 슬리피지 1틱
     )

13.3 기본 진입/청산 함수

함수역할설명
strategy.entry()진입 주문롱/숏 포지션 진입, 반대 포지션 자동 청산
strategy.close()특정 포지션 청산이름으로 지정한 포지션 닫기
strategy.close_all()전체 청산모든 열린 포지션 닫기
strategy.exit()출구 전략 설정TP/SL/트레일링 스탑 설정
strategy.order()단순 주문방향 자동 반전 없이 주문
strategy.cancel()주문 취소대기 중인 주문 취소

13.4 첫 번째 전략 만들기

Pine Script
//@version=6
strategy("MA 크로스 전략", overlay = true, 
     initial_capital = 10000, default_qty_type = strategy.percent_of_equity,
     default_qty_value = 100)

// 파라미터
fastLen = input.int(10, "Fast MA")
slowLen = input.int(30, "Slow MA")

// 이동평균 계산
fastMA = ta.sma(close, fastLen)
slowMA = ta.sma(close, slowLen)

// 진입 조건
longCondition  = ta.crossover(fastMA, slowMA)
shortCondition = ta.crossunder(fastMA, slowMA)

// 주문 실행
if longCondition
    strategy.entry("Long", strategy.long)

if shortCondition
    strategy.entry("Short", strategy.short)

// 시각화
plot(fastMA, color = color.orange)
plot(slowMA, color = color.blue)

이 코드를 차트에 적용하면 Strategy Tester 탭에서 총 수익, 승률, 최대 낙폭(Max Drawdown), 각 거래의 상세 내역 등을 확인할 수 있습니다.

핵심 개념: strategy.entry()는 동일 방향의 포지션이 이미 있으면 무시되고, 반대 방향의 포지션이 있으면 자동으로 기존 포지션을 닫고 새 포지션을 엽니다(반전). 이것이 strategy.order()와의 핵심 차이입니다.
Chapter 14

전략 주문 함수 심화

14.1 strategy.exit() - 손절/익절 설정

strategy.exit()는 진입 이후의 출구 전략을 정의합니다. 손절(Stop Loss), 익절(Take Profit), 트레일링 스탑을 한 번에 설정할 수 있습니다.

Pine Script
//@version=6
strategy("손절/익절 전략", overlay = true, initial_capital = 10000)

longCond = ta.crossover(ta.ema(close, 9), ta.ema(close, 21))

if longCond
    strategy.entry("Long", strategy.long)

// 방법 1: 고정 비율 손절/익절
strategy.exit("TP/SL", "Long", 
     profit = 200,     // 200틱 이익 시 청산
     loss = 100        // 100틱 손실 시 청산
     )

// 방법 2: 가격 기반 손절/익절
entryPrice = strategy.position_avg_price
strategy.exit("TP/SL", "Long",
     limit = entryPrice * 1.03,  // +3% 익절
     stop  = entryPrice * 0.98   // -2% 손절
     )

// 방법 3: 트레일링 스탑
strategy.exit("Trail", "Long",
     trail_points = 100,    // 100틱 이상 수익 후 활성화
     trail_offset = 50      // 고점 대비 50틱 하락 시 청산
     )

14.2 주문 유형 (Market, Limit, Stop)

Pine Script
// 시장가 주문 (Market Order) - 기본
strategy.entry("Long", strategy.long)

// 지정가 주문 (Limit Order) - 현재가 아래에서 매수
strategy.entry("Long", strategy.long, limit = close * 0.99)

// 스탑 주문 (Stop Order) - 가격이 올라가면 매수
strategy.entry("Long", strategy.long, stop = close * 1.01)

// 스탑-리밋 주문 (Stop-Limit Order)
strategy.entry("Long", strategy.long, 
     stop = close * 1.01, limit = close * 1.015)

14.3 포지션 정보 변수

변수설명
strategy.position_size현재 포지션 크기 (양수=롱, 음수=숏, 0=없음)
strategy.position_avg_price현재 포지션의 평균 진입가
strategy.equity현재 자산(자본금 + 실현/미실현 손익)
strategy.openprofit현재 미실현 손익
strategy.netprofit총 순이익
strategy.wintrades승리 거래 수
strategy.losstrades손실 거래 수

14.4 피라미딩 (추가 매수)

기본적으로 strategy.entry()는 같은 방향의 포지션이 있으면 추가 주문을 무시합니다. 피라미딩을 허용하면 같은 방향으로 여러 번 진입할 수 있습니다.

Pine Script
// pyramiding = 3 : 최대 3번까지 같은 방향으로 추가 진입 가능
strategy("피라미딩 전략", overlay = true, pyramiding = 3)
Chapter 15

백테스팅과 성과 분석

15.1 Strategy Tester 읽는 법

전략을 차트에 적용하면 하단에 "Strategy Tester" 탭이 활성화됩니다. 여기에 네 가지 하위 탭이 있습니다.

  • Overview (개요) : 자산 곡선(Equity Curve), 낙폭(Drawdown), Buy & Hold 대비 성과를 한눈에 보여줍니다.
  • Performance Summary (성과 요약) : 총 수익률, 승률, 수익 팩터, 최대 낙폭 등 핵심 지표를 전체/롱/숏별로 분류해 보여줍니다.
  • List of Trades (거래 목록) : 각 거래의 진입/청산 시점, 가격, 수량, 손익을 시간순으로 나열합니다.
  • Properties (속성) : 전략의 설정값(초기 자본, 수수료 등)과 테스트 범위를 표시합니다.

15.2 핵심 성과 지표 해석

지표의미좋은 기준 (참고)
Net Profit총 순이익 (수수료 차감 후)양수
Percent Profitable승률 (%)전략 유형에 따라 다름
Profit Factor총 이익 / 총 손실1.5 이상
Max Drawdown최대 낙폭 (고점 대비 최대 손실)20% 이내
Sharpe Ratio위험 대비 수익률1.0 이상
Average Trade거래당 평균 손익수수료보다 커야 함

15.3 백테스팅 주의사항

백테스팅의 함정:
  • 과적합(Overfitting) : 과거 데이터에 너무 맞추면 미래에는 작동하지 않습니다. 지나치게 많은 파라미터를 최적화하지 마세요.
  • 미래 정보 편향(Look-ahead Bias) : 아직 알 수 없는 미래 데이터를 사용하면 결과가 비현실적입니다.
  • 슬리피지/수수료 미반영 : 반드시 현실적인 수수료와 슬리피지를 설정하세요.
  • 유동성 무시 : 백테스트는 항상 주문이 체결된다고 가정하지만, 실제로는 그렇지 않을 수 있습니다.

15.4 브로커 에뮬레이터 동작 원리

TradingView의 브로커 에뮬레이터는 차트 데이터만을 사용해 주문 체결을 시뮬레이션합니다. 히스토리 봉에서는 봉이 닫힌 후에 주문이 체결되고, 실시간에서는 새로운 틱이 올 때 체결됩니다. 즉, 주문을 생성한 같은 봉에서 바로 체결되지 않고, 다음 봉의 시가에서 체결됩니다.

Chapter 16

알림(Alert) 설정

16.1 alertcondition() - 인디케이터 알림

인디케이터에서는 alertcondition()을 사용합니다. 이 함수는 알림 조건을 정의하고, 사용자가 TradingView UI에서 해당 조건에 알림을 설정할 수 있게 합니다.

Pine Script
//@version=6
indicator("알림 지표", overlay = true)

rsi = ta.rsi(close, 14)
ma  = ta.sma(close, 20)

// 알림 조건 정의 (코드에서는 정의만, 실제 알림은 UI에서 설정)
alertcondition(rsi < 30, title = "RSI 과매도", 
    message = "RSI가 30 이하로 진입했습니다. 현재 RSI: {{plot_0}}")

alertcondition(ta.crossover(close, ma), title = "MA 상향돌파",
    message = "종가가 20일 이동평균을 돌파했습니다.")

plot(rsi, display = display.data_window)
plot(ma)

16.2 alert() - 전략 알림

alert() 함수는 전략 스크립트에서 조건이 충족될 때 즉시 알림을 발생시킵니다. 웹훅(Webhook)과 결합하면 자동매매 시스템을 구축할 수 있습니다.

Pine Script
//@version=6
strategy("웹훅 전략", overlay = true)

longCond = ta.crossover(ta.ema(close, 9), ta.ema(close, 21))

if longCond
    strategy.entry("Long", strategy.long)
    // 웹훅용 JSON 메시지
    alert('{"action":"buy","symbol":"' + syminfo.ticker + '","price":' + str.tostring(close) + '}', 
        alert.freq_once_per_bar_close)

16.3 웹훅(Webhook) 연동

TradingView 알림을 외부 서비스(자동매매 봇, Telegram, Discord 등)에 연동하려면 알림 설정 시 "Webhook URL"을 입력합니다. Pine Script의 alert 메시지를 JSON 형태로 구성하면, 외부 서버에서 이를 파싱하여 자동으로 주문을 실행할 수 있습니다.

알림 빈도 옵션: alert.freq_once_per_bar (봉당 1회), alert.freq_once_per_bar_close (봉 확정 시 1회 - 가장 안정적), alert.freq_all (모든 틱에서)
Chapter 17

멀티 타임프레임 (request.security)

17.1 request.security() 함수

현재 차트의 타임프레임과 다른 타임프레임의 데이터를 가져올 때 사용합니다. 예를 들어 5분봉 차트에서 일봉의 이동평균을 참고하거나, 주봉의 지지/저항선을 표시할 수 있습니다.

Pine Script
//@version=6
indicator("멀티 타임프레임", overlay = true)

// 일봉의 종가
dailyClose = request.security(syminfo.tickerid, "D", close)

// 일봉의 20일 이동평균
dailyMA = request.security(syminfo.tickerid, "D", ta.sma(close, 20))

// 주봉의 고가/저가
weeklyHigh = request.security(syminfo.tickerid, "W", high)
weeklyLow  = request.security(syminfo.tickerid, "W", low)

// 4시간봉의 RSI
h4Rsi = request.security(syminfo.tickerid, "240", ta.rsi(close, 14))

plot(dailyMA, "일봉 MA20", color = color.yellow, linewidth = 3)
plot(weeklyHigh, "주봉 고가", color = color.red, style = plot.style_stepline)
plot(weeklyLow, "주봉 저가", color = color.green, style = plot.style_stepline)

17.2 타임프레임 문자열

문자열타임프레임문자열타임프레임
"1"1분"60"1시간
"5"5분"240"4시간
"15"15분"D"일봉
"30"30분"W"주봉
"45"45분"M"월봉

17.3 v6의 동적 request (Dynamic Requests)

Pine Script v6에서 가장 큰 개선 중 하나는 동적 심볼/타임프레임 요청입니다. v5에서는 request.security()의 심볼과 타임프레임이 반드시 상수여야 했지만, v6에서는 변수를 사용할 수 있습니다.

Pine Script
//@version=6
indicator("다중 심볼 비교")

// v6에서 가능해진 동적 심볼 요청
symbol1 = input.symbol("BINANCE:BTCUSDT", "심볼 1")
symbol2 = input.symbol("BINANCE:ETHUSDT", "심볼 2")

price1 = request.security(symbol1, timeframe.period, close)
price2 = request.security(symbol2, timeframe.period, close)

// 상대 강도 비교
plot(price1 / price1[1] * 100 - 100, "심볼1 변화율", color = color.blue)
plot(price2 / price2[1] * 100 - 100, "심볼2 변화율", color = color.orange)
hline(0)
중요 규칙: request.security()에서 더 낮은 타임프레임의 데이터를 요청할 때(예: 일봉 차트에서 1분봉 데이터)는 데이터 양의 제한으로 인해 결과가 부정확할 수 있습니다. 일반적으로 현재 차트와 같거나 더 높은 타임프레임의 데이터를 요청하는 것이 안전합니다.
Chapter 18

배열과 컬렉션

18.1 배열 (Array) 기초

배열은 같은 타입의 여러 값을 하나의 변수에 저장합니다. Pine Script에서 배열은 최근 N개의 값을 추적하거나, 동적으로 데이터를 관리할 때 유용합니다.

Pine Script
//@version=6
indicator("배열 예시")

// 배열 생성
var prices = array.new_float(0)

// 매 봉마다 종가 추가
array.push(prices, close)

// 최대 50개만 유지
if array.size(prices) > 50
    array.shift(prices)  // 가장 오래된 값 제거

// 배열 활용
avgPrice = array.avg(prices)
maxPrice = array.max(prices)
minPrice = array.min(prices)
lastPrice = array.get(prices, -1)  // v6: 음수 인덱싱!

plot(avgPrice, "평균")

18.2 주요 배열 함수

함수설명
array.new_float(size)float 배열 생성
array.push(arr, val)끝에 값 추가
array.pop(arr)끝에서 값 제거 및 반환
array.shift(arr)앞에서 값 제거 및 반환
array.get(arr, idx)인덱스로 값 가져오기
array.set(arr, idx, val)인덱스에 값 설정
array.size(arr)배열 크기
array.avg(arr)평균값
array.max(arr)최대값
array.min(arr)최소값
array.sort(arr)정렬

18.3 맵 (Map) - 키-값 저장

맵은 키-값 쌍으로 데이터를 저장합니다. 심볼별 데이터를 관리하거나, 레이블을 붙인 값을 관리할 때 유용합니다.

Pine Script
//@version=6
indicator("맵 예시")

// 맵 생성
var levels = map.new<string, float>()

// 키-값 쌍 저장
map.put(levels, "support", ta.lowest(low, 20))
map.put(levels, "resistance", ta.highest(high, 20))
map.put(levels, "pivot", (high[1] + low[1] + close[1]) / 3)

// 값 가져오기
plot(map.get(levels, "support"), "지지", color = color.green)
plot(map.get(levels, "resistance"), "저항", color = color.red)
plot(map.get(levels, "pivot"), "피봇", color = color.gray)
Chapter 19

실전 전략 프로젝트

19.1 RSI + SuperTrend 복합 전략

지금까지 배운 모든 개념을 종합하여 실전에서 사용할 수 있는 전략을 만들어 봅니다. RSI로 과매수/과매도를 판단하고, SuperTrend로 추세 방향을 확인한 후, 두 조건이 동시에 충족될 때만 진입하는 전략입니다.

Pine Script
//@version=6
strategy("RSI + SuperTrend 전략", overlay = true,
     initial_capital = 10000,
     default_qty_type = strategy.percent_of_equity,
     default_qty_value = 95,
     commission_type = strategy.commission.percent,
     commission_value = 0.1,
     slippage = 2)

// ===== 입력값 =====
grpST = "SuperTrend 설정"
atrLen  = input.int(10, "ATR 기간", group = grpST)
factor  = input.float(3.0, "ATR 배수", group = grpST, step = 0.1)

grpRSI = "RSI 설정"
rsiLen  = input.int(14, "RSI 기간", group = grpRSI)
rsiOB   = input.int(70, "과매수 기준", group = grpRSI)
rsiOS   = input.int(30, "과매도 기준", group = grpRSI)

grpRisk = "리스크 관리"
slPct   = input.float(3.0, "손절 (%)", group = grpRisk)
tpPct   = input.float(6.0, "익절 (%)", group = grpRisk)

// ===== 지표 계산 =====
[supertrend, stDir] = ta.supertrend(factor, atrLen)
rsi = ta.rsi(close, rsiLen)

// 추세 판단
upTrend   = stDir < 0   // SuperTrend 상승
downTrend = stDir > 0   // SuperTrend 하락

// ===== 진입 조건 =====
longCondition  = upTrend and ta.crossover(rsi, rsiOS)
shortCondition = downTrend and ta.crossunder(rsi, rsiOB)

// ===== 주문 실행 =====
if longCondition
    strategy.entry("Long", strategy.long)
    strategy.exit("Long Exit", "Long",
         limit = close * (1 + tpPct/100),
         stop  = close * (1 - slPct/100))

if shortCondition
    strategy.entry("Short", strategy.short)
    strategy.exit("Short Exit", "Short",
         limit = close * (1 - tpPct/100),
         stop  = close * (1 + slPct/100))

// ===== 시각화 =====
stColor = upTrend ? color.green : color.red
plot(supertrend, "SuperTrend", color = stColor, linewidth = 2)
bgcolor(color.new(stColor, 95))

plotshape(longCondition, "매수 진입", shape.triangleup,
    location.belowbar, color.green, size = size.small)
plotshape(shortCondition, "매도 진입", shape.triangledown,
    location.abovebar, color.red, size = size.small)

19.2 전략 개선 포인트

위 전략은 기본적인 뼈대입니다. 실전에서 더 좋은 성과를 위해 다음을 추가로 고려하세요.

  • 거래 시간 필터 : 변동성이 큰 시간대에만 거래 (예: 런던 + 뉴욕 세션)
  • 추세 강도 필터 : ADX > 25일 때만 진입하여 횡보장 회피
  • 거래량 확인 : 평균 거래량 이상일 때만 진입
  • 연속 손실 제한 : 3연패 시 당일 거래 중단
  • 동적 손절 : ATR 기반으로 변동성에 맞는 손절폭 설정
Chapter 20

부록 - Pine Script 치트시트 & 학습 가이드

20.1 Pine Script 핵심 문법 치트시트

Pine Script Cheat Sheet
/* =============================================
   Pine Script v6 치트시트
   ============================================= */

/* ── 1. 스크립트 선언 ── */
//@version=6
indicator("이름", overlay = true/false)
strategy("이름", overlay = true, initial_capital = 10000)
library("이름")

/* ── 2. 변수 선언 ── */
myVar = close                   // 타입 추론
int myInt = 14                  // 명시적 선언
var float persist = 0.0         // 값 유지 변수
varip int tickVar = 0           // 틱 유지 변수

/* ── 3. 가격 데이터 ── */
open, high, low, close, volume
hl2, hlc3, ohlc4
close[1]   // 1봉 전 종가
close[N]   // N봉 전 종가

/* ── 4. 이동평균 ── */
ta.sma(src, length)    // 단순
ta.ema(src, length)    // 지수
ta.wma(src, length)    // 가중
ta.vwma(src, length)   // 거래량가중
ta.rma(src, length)    // 와일더

/* ── 5. 오실레이터 ── */
ta.rsi(src, length)
ta.macd(src, fast, slow, signal)  // → [line, signal, hist]
ta.stoch(close, high, low, length)
ta.atr(length)
ta.bb(src, length, mult)         // → [upper, middle, lower]
ta.supertrend(factor, atrLen)    // → [value, direction]

/* ── 6. 크로스 / 최고최저 ── */
ta.crossover(a, b)      // a가 b를 상향 돌파
ta.crossunder(a, b)     // a가 b를 하향 돌파
ta.highest(src, len)    // 최근 len봉 최고값
ta.lowest(src, len)     // 최근 len봉 최저값
ta.barssince(cond)      // 조건 충족 후 경과 봉 수

/* ── 7. 시각화 ── */
plot(value, title, color, linewidth, style)
hline(price, title, color)
fill(plot1, plot2, color)
bgcolor(color)
barcolor(color)
plotshape(cond, shape, location, color)
label.new(x, y, text, color, textcolor)
line.new(x1, y1, x2, y2, color)

/* ── 8. 입력값 ── */
input.int(defval, title, minval, maxval)
input.float(defval, title, step)
input.bool(defval, title)
input.string(defval, title, options)
input.color(defval, title)
input.source(defval, title)
input.timeframe(defval, title)
input.symbol(defval, title)

/* ── 9. 전략 함수 ── */
strategy.entry(id, direction, qty, limit, stop)
strategy.exit(id, from_entry, profit, loss, limit, stop,
              trail_points, trail_offset)
strategy.close(id)
strategy.close_all()
strategy.cancel(id)
strategy.cancel_all()

/* ── 10. 멀티 타임프레임 ── */
request.security(symbol, timeframe, expression)

/* ── 11. 알림 ── */
alertcondition(condition, title, message)
alert(message, freq)

/* ── 12. 유용한 함수 ── */
math.abs(x)  |  math.round(x)  |  math.max(a, b)
str.tostring(val, format)
na(value)    // na 여부 확인
nz(value, replacement)  // na를 대체값으로
color.new(col, transparency)  // 투명도 설정 (0~100)
color.from_gradient(val, low, high, col1, col2)

20.2 자주 하는 실수 & 해결법

실수증상해결법
var 미사용으로 값 초기화됨카운터가 항상 0~1누적 변수에 var 키워드 사용
na 값 비교를 == 로 함조건이 작동하지 않음na() 함수로 확인
strategy.exit를 if문 안에 넣음조건 변경 시 exit 사라짐entry 직후에 exit 설정
request.security 결과가 이상함미래 데이터 참조lookahead=barmerge.lookahead_off 확인
라벨/선이 무한 생성차트 느려짐이전 객체 삭제 또는 if barstate.islast 사용
overlay=false인데 가격 표시 안 됨별도 패널에 그려짐overlay=true로 변경
전략 수익이 비현실적수수료/슬리피지 미반영strategy()에 commission, slippage 설정
봉 확정 전 신호가 깜빡임실시간에서 신호 번복barstate.isconfirmed 조건 추가

20.3 Pine Script 실행 순서 (핵심 개념)

바-by-바 실행 모델:
Pine Script는 차트의 첫 봉(bar_index=0)부터 마지막 봉까지 순서대로 전체 코드를 반복 실행합니다.

각 봉에서의 실행 흐름:
① 내장 변수 갱신 (open, high, low, close, volume 등) →
② 스크립트 코드 위에서 아래로 실행 →
③ plot, label 등 출력 처리 →
④ 다음 봉으로 이동

이 모델을 이해하면 var의 동작, []의 의미, 전략 주문이 "다음 봉 시가"에 체결되는 이유가 명확해집니다.

20.4 학습 로드맵

단계기간학습 내용이 튜토리얼
Level 1 입문1~2주환경 설정, 기본 문법, plot, inputCh.1 ~ Ch.8
Level 2 기초2~3주ta.* 함수, 인디케이터 제작, 조건부 시각화Ch.9 ~ Ch.12
Level 3 중급3~4주전략 작성, 백테스팅, 알림, 멀티 타임프레임Ch.13 ~ Ch.17
Level 4 고급1~2개월배열, 맵, 테이블, UDT, 라이브러리 제작Ch.18 + 추가 학습
Level 5 실전지속복합 전략, 최적화, 웹훅 자동화, 포트폴리오Ch.19 + 실전 경험

20.5 공식 참고 자료

  • Pine Script Reference Manual : tradingview.com/pine-script-reference/v6/ (모든 함수/변수의 공식 문서)
  • Pine Script User Manual : tradingview.com/pine-script-docs (개념 설명 + 예제)
  • TradingView 커뮤니티 스크립트 : 다른 사람의 코드를 읽으며 배우기
  • Pine Script Q&A : Stack Overflow 'pine-script' 태그

20.6 마치며

축하합니다! 전 20장의 Pine Script 사용법 총정리 튜토리얼을 모두 마치셨습니다.

Pine Script는 트레이더에게 "아이디어를 검증하는 능력"을 줍니다. 머릿속에 있는 매매 전략을 코드로 옮기고, 과거 데이터로 검증하고, 조건이 맞으면 알림을 받는 것. 이것이 Pine Script를 배우는 궁극적인 목표입니다.

Pine Script 학습의 핵심 3원칙:

1. 작은 것부터 시작하세요 — 처음부터 복잡한 전략을 만들려 하지 마세요. 단순한 이동평균 하나를 그리는 것에서 시작하여 점진적으로 기능을 추가하세요.

2. 공식 문서를 친구로 삼으세요 — Pine Script Reference Manual은 모든 함수의 파라미터, 반환값, 예제를 포함합니다. 모르는 함수가 있으면 항상 레퍼런스를 먼저 찾으세요.

3. 다른 사람의 코드를 읽으세요 — TradingView에 공개된 수천 개의 스크립트는 최고의 학습 자료입니다. "Open Source"로 필터링하여 인기 있는 스크립트의 코드를 분석해 보세요.

여러분의 트레이딩 아이디어를 코드로 실현하는 여정에 이 튜토리얼이 든든한 기반이 되기를 바랍니다. 성공적인 트레이딩을 응원합니다!